#coding:utf-8
import redis
import random

'''
    redis操作类
'''

#设置静态常量
MAX_SCORE = 100
MIN_SCORE = 0
INITIAL_SCORE = 10

REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_PASSWORD = None
REDIS_KEY = 'proxies'

class RedisClient(object):
    def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD):
        '''
            作用：redis操作相关类，通过此类进行redis有序集合数据的操作设置
            :param host: redis的地址
            :param port: redis的端口
            :param password: redis的密码
        '''
        self.db = redis.StrictRedis(host=host, port=port, password=password, decode_responses=True)

    def add(self, proxy, score=INITIAL_SCORE):
        '''
            作用：添加新的代理，设置分数为初始值10
            :param proxy: 代理
            :param score: 分数
            :return 添加结果
        '''
        #从redis_key中获取值为proxy的分数，如果不存在，则添加新的值
        if not self.db.zscore(REDIS_KEY, proxy):
            return self.db.zadd(REDIS_KEY, score, proxy)

    def random(self):
        '''
            作用：获取随机有效的代理，尝试从最高分代理开始获取，如果高分不存在，则按照排名获取，否则异常
            :return 随机可用代理
        '''
        result = self.db.zrangebyscore(REDIS_KEY, MAX_SCORE, MAX_SCORE)
        if len(result):
            return random.choice(result)
        else:
            result = self.db.zrevrange(REDIS_KEY, 0, 100)
            if len(result):
                return random.choice(result)
            else:
                raise 'PoolEmptyError'

    def decrease(self, proxy):
        '''
            作用：代理的分数值减一分，分数值小于最小值，则代理删除
            :param proxy: 代理
            :return 修改后的分数
        '''
        score = self.db.zscore(REDIS_KEY, proxy)
        if score and score > MIN_SCORE:
            print('代理', proxy, '当前分数', score, '减1')
            return self.db.zincrby(REDIS_KEY, proxy, -1)
        else:
            print('代理', proxy, '当前分数', score, '移除')
            return self.db.zrem(REDIS_KEY, proxy)

    def exists(self, proxy):
        '''
            作用：判断代理是否存在
            :param proxy: 代理
            :return 是否存在
        '''
        return not self.db.zscore(REDIS_KEY, proxy) == None

    def max(self, proxy):
        '''
            作用：将代理设置为分数最大值
            :param proxy: 代理
            :return 设置结果
        '''
        print('代理', proxy, '可用，分数设置为：', MAX_SCORE)
        return self.db.zadd(REDIS_KEY, MAX_SCORE, proxy)

    def count(self):
        '''
            作用：获取代理总数量
            :return 总数量
        '''
        return self.db.zcard(REDIS_KEY)

    def all(self):
        '''
            作用：获取全部代理
            :return 全部代理列表
        '''
        return self.db.zrangebyscore(REDIS_KEY, MIN_SCORE, MAX_SCORE)


